/*
 Copyright (c) 2013 MeherTJ G. All rights reserved.
 License: LGPL for personnal study or free software.
 */

#include "zen_gles2_shader_kit.h"
#include "zen_color.h"
#include "zen_gles2_shader_kit.es.h"

#define SHADER_GET_ATT(s, x) \
do { \
if(v.find(#x) != std::string::npos || f.find(#x) != std::string::npos) \
s->x = s->program().getAttributeLocation(#x); \
} while(0)

#define SHADER_GET_UNI(s, x) \
do { \
if(v.find(#x) != std::string::npos || f.find(#x) != std::string::npos) \
s->x = s->program().getUniformLocation(#x); \
} while(0)

namespace Zen { namespace GL {
	ShaderKitColors::Shared ShaderKitColors::GetNormal()
	{
		static auto e = Create(VS_Color, FS_Color);
		return e;
	}
	ShaderKitColors::Shared ShaderKitColors::GetToGrey()
	{
		static auto e = Create(VS_Color, FS_Color_g);
		return e;
	}

	ShaderKitColors::Shared ShaderKitColors::Create(std::string const & v, std::string const & f)
	{
		auto s = Shared(new ShaderKitColors);
		s->bindProgram(v, f);

		SHADER_GET_ATT(s, a_coord);
		SHADER_GET_ATT(s, a_color);
		SHADER_GET_UNI(s, u_transform);
		SHADER_GET_UNI(s, u_color);
		SHADER_GET_UNI(s, u_grey_factor);

		return s;
	}

	ShaderKitPoints::Shared ShaderKitPoints::GetNormal()
	{
		static auto e = Create(VS_Point, FS_Point_T);
		return e;
	}
	ShaderKitPoints::Shared ShaderKitPoints::GetToGrey()
	{
		static auto e = Create(VS_Point, FS_Point_T_g);
		return e;
	}

	ShaderKitPoints::Shared ShaderKitPoints::GetWithoutTexture()
	{
		static auto e = Create(VS_Point, FS_Point);
		return e;
	}

	ShaderKitPoints::Shared ShaderKitPoints::GetWithoutTextureToGrey()
	{
		static auto e = Create(VS_Point, FS_Point_g);
		return e;
	}
	ShaderKitPoints::Shared ShaderKitPoints::GetWithAlphaTexture()
	{
		static auto e = Create(VS_Point, FS_Point_T_A);
		return e;
	}
	ShaderKitPoints::Shared ShaderKitPoints::GetWithAlphaTextureToGrey()
	{
		static auto e = Create(VS_Point, FS_Point_T_Ag);
		return e;
	}
	ShaderKitPoints::Shared ShaderKitPoints::Create(std::string const & v, std::string const & f)
	{
		auto s = Shared(new ShaderKitPoints);
		s->bindProgram(v, f);

		SHADER_GET_ATT(s, a_coord);
		SHADER_GET_ATT(s, a_point_size);
		SHADER_GET_ATT(s, a_color);

		SHADER_GET_UNI(s, u_transform);
		SHADER_GET_UNI(s, u_point_size_ratio);
		SHADER_GET_UNI(s, u_color);
		SHADER_GET_UNI(s, u_sampler);
		SHADER_GET_UNI(s, u_grey_factor);

		return s;
	}
	
	ShaderKitTexture::Shared ShaderKitTexture::GetNormal()
	{
		static auto e = Create(VS_Texture, FS_Texture);
		return e;
	}
	ShaderKitTexture::Shared ShaderKitTexture::GetToGrey()
	{
		static auto e = Create(VS_Texture, FS_Texture_g);
		return e;
	}
	ShaderKitTexture::Shared ShaderKitTexture::GetWithAlphaTexture()
	{
		static auto e = Create(VS_Texture, FS_Texture_A);
		return e;
	}
	ShaderKitTexture::Shared ShaderKitTexture::GetWithAlphaTextureToGrey()
	{
		static auto e = Create(VS_Texture, FS_Texture_Ag);
		return e;
	}
	ShaderKitTexture::Shared ShaderKitTexture::GetWithoutTexture()
	{
		static auto e = Create(VS_Texture, FS_Texture_no_sampler);
		return e;
	}
	ShaderKitTexture::Shared ShaderKitTexture::GetWithoutTextureToGrey()
	{
		static auto e = Create(VS_Texture, FS_Texture_no_sampler_g);
		return e;
	}
	ShaderKitTexture::Shared ShaderKitTexture::Create(std::string const & v, std::string const & f)
	{
		auto s = Shared(new ShaderKitTexture);
		s->bindProgram(v, f);
		SHADER_GET_ATT(s, a_coord);
		SHADER_GET_ATT(s, a_tex_coord);
		SHADER_GET_UNI(s, u_transform);
		SHADER_GET_UNI(s, u_color);
		SHADER_GET_UNI(s, u_sampler);
		SHADER_GET_UNI(s, u_tex_rect);
		SHADER_GET_UNI(s, u_grey_factor);

		return s;
	}
	
}}
